﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Timers;
using System.Text.RegularExpressions;
using System.Configuration;

namespace MovieApp
{
    public class MovieHandler : ApplicationSettingsBase
    {
        private bool dirty;
        private Timer timer;
        private SettingsHandler settings;
        private List<Movie> tempList;

        public MovieHandler()
        {
            dirty = false;
            settings = new SettingsHandler();
            this.Reload();
            tempList = Movies;

            if (settings.AutoSave)
            {
                timer = new Timer(settings.AutoSaveIntervalMs);//5 min timer
                timer.AutoReset = true;
                timer.Elapsed += new ElapsedEventHandler(UpdateMovieList);
                timer.Start();
            }
        }

        [UserScopedSetting]
        public List<Movie> Movies
        {
            get {
                if (this["Movies"] == null)
                    return new List<Movie>();
                return (List<Movie>)this["Movies"]; 
            }
            set { this["Movies"] = value; }
        }

        public void WatchMovie(string path)
        {
            if (!MovieSeen(path) && IsMovie(path))
            {
                dirty = true;
                tempList.Add(new Movie() {
                    Name = path,
                    Elapsed = 0
                });
            }
        }

        public bool MovieSeen(string path)
        {
            foreach (Movie movie in tempList)
                if (movie.Name == path)
                    return true;
            return false;
        }

        public void UpdateMovieList(object sender = null, ElapsedEventArgs e = null)
        {
            //nothing to save
            if (sender != null && !dirty)
                return;

            //TODO sort movie list
            this.Movies = tempList;

            this.Save();
            dirty = false;
        }

        public static bool IsMovie(string fileName)
        {
            string[] exts = { ".avi", ".mkv" };
            foreach (string ext in exts)
                if (fileName.Contains(ext))
                    return true;
            return false;
        }

        private static Match GetMatch(string fileName)
        {
            Regex reg1 = new Regex(@"(([a-z]+\.)*)s([\d]+)e([\d]+)", RegexOptions.IgnoreCase);
            Regex reg2 = new Regex(@"(([a-z]+\.)*)([\d]+)", RegexOptions.IgnoreCase);
            var match = reg1.Match(fileName);
            
            if (match.Success)
                return match;

            match = reg2.Match(fileName);
            return match;
        }

        public static string GetSeasonNumber(string fileName)
        {
            var match = GetMatch(fileName);
            if (match.Success)
            {
                string grp = match.Groups[match.Groups.Count - 2].ToString();
                int n;
                //check if value is numeric
                if (!int.TryParse(grp, out n))
                    grp = match.Groups[match.Groups.Count - 1].ToString();
                
                string ret = grp;
                if (grp.Length > 2)
                {
                    if (grp.Length == 3)
                        ret = grp.Substring(0,1);
                    if (grp.Length == 4)
                        ret = grp.Substring(0, 2);
                }

                int.TryParse(ret, out n);

                return n.ToString();
            }
            return "";
        }

        public static string GetEpisodeNumber(string fileName)
        {
            var match = GetMatch(fileName);
            if (match.Success)
            {
                string grp = match.Groups[ match.Groups.Count - 1 ].ToString();
                int n;
                string ret = grp;
                if (grp.Length > 2)
                {
                    if (grp.Length == 3)
                        ret = grp.Substring(1, 2);
                    if (grp.Length == 4)
                        ret = grp.Substring(2, 2);
                }

                int.TryParse(ret, out n);

                return n.ToString();
            }
            return "";
        }

        private static string UppercaseWords(string value)
        {
            char[] array = value.ToCharArray();
            // Handle the first letter in the string.
            if (array.Length >= 1)
            {
                if (char.IsLower(array[0]))
                {
                    array[0] = char.ToUpper(array[0]);
                }
            }
            // Scan through the letters, checking for spaces.
            // ... Uppercase the lowercase letters following spaces.
            for (int i = 1; i < array.Length; i++)
            {
                if (array[i - 1] == ' ')
                {
                    if (char.IsLower(array[i]))
                    {
                        array[i] = char.ToUpper(array[i]);
                    }
                }
            }
            return new string(array);
        }

        public static string GetShowName(string fileName)
        {
            var match = GetMatch(fileName);
            if (match.Success)
            {
                string ret = match.Groups[1].ToString().Replace(".", " ");
                ret = ret.Trim();
                ret = UppercaseWords(ret);
                return ret;
            }
            return "";
        }
    }
}
